use async_graphql::{Context, Object, Result, SimpleObject};
use minio_rsc::Minio;
use std::time::Duration;
use minio_rsc::client::PresignedArgs;

#[derive(SimpleObject)]
pub struct FileResponse {
    pub url: String,
    pub expires_in_seconds: u32,
}



#[derive(Default)]
pub struct FileQuery;

#[Object]
impl FileQuery {
    /// 获取文件下载链接
    async fn get_file_download_url(
        &self,
        ctx: &Context<'_>,
        bucket_name: String,
        object_name: String,
        expires_in_seconds: Option<u32>,
    ) -> Result<FileResponse> {
        let minio = ctx.data::<Minio>()?;

        // 过期默认1小时
        let expr = expires_in_seconds.unwrap_or(3600);

        let url = minio
            .presigned_get_object(
                PresignedArgs::new(bucket_name, object_name)
                    .expires(expr as usize)
            )
            .await
            .map_err(|e| async_graphql::Error::new(format!("Failed to generate download URL: {}", e)))?;


        Ok(FileResponse {
            url,
            expires_in_seconds: expr,
        })
    }

    /// 获取文件上传链接
    async fn get_file_upload_url(
        &self,
        ctx: &Context<'_>,
        bucket_name: String,
        object_name: String,
        expires_in_seconds: Option<u32>,
    ) -> Result<FileResponse> {
        let minio = ctx.data::<Minio>()?;

        // 过期默认1小时
        let expr = expires_in_seconds.unwrap_or(3600);

        let url = minio
            .presigned_put_object(
                PresignedArgs::new(&bucket_name, &object_name)
                    .expires(expr as usize),
            )
            .await
            .map_err(|e| async_graphql::Error::new(format!("Failed to generate upload URL: {}", e)))?;

        Ok(FileResponse {
            url,
            expires_in_seconds: expr,
        })
    }
}
